package com.huangfuyi.datasource.service;

import com.huangfuyi.common.utils.ObjectUtils;
import com.huangfuyi.datasource.entity.EConnectConf;
import com.huangfuyi.datasource.entity.EDataQueryCondition;
import com.huangfuyi.datasource.entity.EDataDefineConf;
import com.huangfuyi.datasource.entity.ddl.EFileDataDefineConf;
import com.huangfuyi.datasource.entity.query.EDataQueryResult;
import com.huangfuyi.datasource.exceptions.EDMLExecuteException;

import java.io.*;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;

// 数据源接口
public class EFileDataSource implements EDataSource {


    @Override
    public void init(List<? extends EConnectConf> connectInfo) {

    }

    @Override
    public boolean connectionTest(EConnectConf connectInfo) {
        return false;
    }

    @Override
    public void close() {

    }

    @Override
    public Class<? extends EConnectConf> getConnectInfoExample() {
        return null;
    }

    @Override
    public int dataDefine(EDataDefineConf defineConf) {
        return 0;
    }

    @Override
    public List<Class<? extends EDataDefineConf>> getDataDefineInfoExample() {
        return null;
    }

    @Override
    public int insert(EDataDefineConf defineConf, List<Map<String, Object>> data) {
        if (!(defineConf instanceof EFileDataDefineConf)) {
            throw new EDMLExecuteException("当前传入的不是文件系统数据定义信息。");
        }
        if (ObjectUtils.isEmpty(data)) {
            return 0;
        }

        EFileDataDefineConf fileDataDefineConf = (EFileDataDefineConf) defineConf;

        String path = String.format(Locale.ENGLISH, "./%s/%s/",
                fileDataDefineConf.getDatabase().replaceAll("/", "/"),
                fileDataDefineConf.getTable().replaceAll("/", "/"));

        File dirs = new File(path);
        File file = new File(String.format(Locale.ENGLISH, "%s%s.data", path, fileDataDefineConf.getId()));
        if (!dirs.exists()) {
            if (!dirs.mkdirs()) {
                throw new EDMLExecuteException("创建数据存储目录失败。");
            }
            try {
                if (!file.createNewFile()) {
                    throw new EDMLExecuteException("create返回false");
                }
            } catch (IOException e) {
                throw new EDMLExecuteException(String.format(Locale.ROOT, "创建数据存储文件失败，失败原因： %s;", e.getMessage()), e);
            }
        }
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
            out.writeObject(data.get(0));
        } catch (Exception e) {
            throw new EDMLExecuteException(String.format(Locale.ROOT, "数据写入文件失败，失败原因： %s;", e.getMessage()), e);
        }
        return 1;
    }

    @Override
    public int delete(EDataDefineConf defineConf, EDataQueryCondition condition) {
        if (!(defineConf instanceof EFileDataDefineConf)) {
            throw new EDMLExecuteException("当前传入的不是文件系统数据定义信息。");
        }
        EFileDataDefineConf fileDataDefineConf = (EFileDataDefineConf) defineConf;
        String filePath = String.format(Locale.ENGLISH, "./%s/%s/%s.data",
                fileDataDefineConf.getDatabase().replaceAll("/", "/"),
                fileDataDefineConf.getTable().replaceAll("/", "/"),
                fileDataDefineConf.getId());

        File file = new File(filePath);
        file.deleteOnExit();
        return 1;
    }

    @Override
    public int update(EDataDefineConf defineConf, Map<String, Object> data, EDataQueryCondition condition) {
        return 0;
    }

    @Override
    public EDataQueryResult select(EDataDefineConf defineConf, EDataQueryCondition condition) {
        if (!(defineConf instanceof EFileDataDefineConf)) {
            throw new EDMLExecuteException("当前传入的不是文件系统数据定义信息。");
        }
        EFileDataDefineConf fileDataDefineConf = (EFileDataDefineConf) defineConf;
        String filePath = String.format(Locale.ENGLISH, "./%s/%s/%s.data",
                fileDataDefineConf.getDatabase().replaceAll("/", "/"),
                fileDataDefineConf.getTable().replaceAll("/", "/"),
                fileDataDefineConf.getId());

        File file = new File(filePath);
        if (!file.exists()) {
            throw new EDMLExecuteException("文件系统数据查询失败，失败原因： 数据文件不存在;");
        }

        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))) {
            return Collections.singletonList(in.readObject());
        } catch (Exception e) {
            throw new EDMLExecuteException(String.format(Locale.ROOT, "数据写入文件失败，失败原因： %s;", e.getMessage()), e);
        }
    }
}
